﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.Windows.Forms;
using LCARSLibrary;
using LCARSLibrary.Controls;
using LCARSLibrary.VerbalInterface;

using Settings = Cepheus.Settings<LCARS_Interface.MISettings>;

namespace LCARS_Interface
{
    public partial class FormMain : Form
    {
        #region Platform Invoke

        const int WM_HOTKEY = 0x0312;
        const int WM_DISPLAYCHANGE = 0x007E;

        [DllImport("user32")]
        static extern int RegisterHotKey(IntPtr hWnd, int id, int modifiers, int key);

        [DllImport("user32")]
        static extern int UnregisterHotKey(IntPtr hWnd, int id);

        [DllImport("user32.dll")]
        static extern bool SetForegroundWindow(IntPtr hWnd);

        #endregion

        VlcInterface vlcInterface;

        Paging<MusicObject, string> pagingMusic;
        Paging<Area, string> pagingDocuments;
        Paging<Area, string> pagingPictures;

        PagingIDBased<Area, Activity> pagingActivities;
        PagingIDBased<Area, Activity.Program> pagingActivityPrograms;

        Dictionary<int, List<LCARSBase>> redAlertFlashingCtrls;

        List<string> musicAlbums;
        List<string> documents;
        List<string> pictures;

        public FormMain()
        {
            InitializeComponent();

            redAlertFlashingCtrls = new Dictionary<int, List<LCARSBase>>();

            redAlertFlashingCtrls.Add(0, new List<LCARSBase>());
            redAlertFlashingCtrls.Add(1, new List<LCARSBase>());
            redAlertFlashingCtrls.Add(2, new List<LCARSBase>());
            redAlertFlashingCtrls.Add(3, new List<LCARSBase>());
            redAlertFlashingCtrls.Add(4, new List<LCARSBase>());
            redAlertFlashingCtrls.Add(5, new List<LCARSBase>());
            redAlertFlashingCtrls.Add(6, new List<LCARSBase>());

            redAlertFlashingCtrls[0].AddRange(LCARSBase.GetGroupControls(ControlGroup.Group0));
            redAlertFlashingCtrls[1].AddRange(LCARSBase.GetGroupControls(ControlGroup.Group01));
            redAlertFlashingCtrls[2].AddRange(LCARSBase.GetGroupControls(ControlGroup.Group02));
            redAlertFlashingCtrls[3].AddRange(LCARSBase.GetGroupControls(ControlGroup.Group03));
            redAlertFlashingCtrls[4].AddRange(LCARSBase.GetGroupControls(ControlGroup.Group04));
            redAlertFlashingCtrls[5].AddRange(LCARSBase.GetGroupControls(ControlGroup.Group05));
            redAlertFlashingCtrls[6].AddRange(LCARSBase.GetGroupControls(ControlGroup.Group06));


            areaTitleSecondary.Text = String.Empty;
            this.Size = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height - 2);

            vlcInterface = new VlcInterface();

            areaPreviousPage.SoundEffect = LCARSLibrary.SoundEffect.Error1;
            areaNextPage.SoundEffect = LCARSLibrary.SoundEffect.Error1;

            FillFileSystemFileLists();

            InitializePaging();

            LoadActivites();

            InitializeVI();

            RegisterHotKey(this.Handle, 1, 0x08/*MOD_WIN*/, 0x49);
        }


        void FillFileSystemFileLists()
        {
            musicAlbums = new List<string>();

            if (!String.IsNullOrEmpty(Settings.Default.Data.MusicPath))
            {
                string[] paths = Settings.Default.Data.MusicPath.Split(';');

                foreach (var path in paths)
                {
                    musicAlbums.AddRange(Utilities.GetOneLevelDirectories(path, new List<string>(new[] { "CD1", "CD 1", "CD2", "CD 2" })));
                }
            }


            documents = new List<string>();

            if (!String.IsNullOrEmpty(Settings.Default.Data.DocumentsPath))
            {
                string[] paths = Settings.Default.Data.DocumentsPath.Split(';');

                foreach (var path in paths)
                {
                    documents.AddRange(Directory.GetDirectories(path));
                    documents.AddRange(Directory.GetFiles(path));
                }
            }


            pictures = new List<string>();

            if (!String.IsNullOrEmpty(Settings.Default.Data.PicturePath))
            {
                string[] paths = Settings.Default.Data.PicturePath.Split(';');

                foreach (var path in paths)
                {
                    pictures.AddRange(Directory.GetDirectories(path));
                    pictures.AddRange(Directory.GetFiles(path));
                }
            }
        }

        void InitializePaging()
        {
            pagingMusic = new Paging<MusicObject, string>()
            {
                Parent = this,
                Data = musicAlbums,
                ControlSize = new Size(devAreaObjects.Width, 35),
                Spacing = new Size(4, 4),
                StartTopLeftPosition = new Point(devAreaObjects.Left, devAreaObjects.Top),
                EndBottomRightPosition = new Point(devAreaObjects.Right, devAreaObjects.Bottom)
            };

            pagingMusic.SetPageDependentControlData += new EventHandler<SetPageDependentControlDataEventArgs<MusicObject, string>>(pagingMusic_SetPageDependentControlData);
            pagingMusic.PageChanged += new EventHandler<PageChangedEventArgs>(paging_PageChanged);
            pagingMusic.InitializeControl += new EventHandler<ControlEventArgs<MusicObject>>(pagingMusic_InitializeControl);
            pagingMusic.VisibleChanged += new EventHandler(pagingMusic_VisibleChanged);
            pagingMusic.InitializeControls();


            pagingDocuments = new Paging<Area, string>()
            {
                Parent = this,
                Data = documents,
                ControlSize = new Size(devAreaObjects.Width, 35),
                Spacing = new Size(4, 4),
                StartTopLeftPosition = new Point(devAreaObjects.Left, devAreaObjects.Top),
                EndBottomRightPosition = new Point(devAreaObjects.Right, devAreaObjects.Bottom)
            };

            pagingDocuments.SetPageDependentControlData += new EventHandler<SetPageDependentControlDataEventArgs<Area, string>>(pagingDocuments_SetPageDependentControlData);
            pagingDocuments.PageChanged += new EventHandler<PageChangedEventArgs>(paging_PageChanged);
            pagingDocuments.InitializeControl += new EventHandler<ControlEventArgs<Area>>(pagingDocuments_InitializeControl);
            pagingDocuments.VisibleChanged += new EventHandler(pagingDocuments_VisibleChanged);
            pagingDocuments.InitializeControls();


            pagingPictures = new Paging<Area, string>()
            {
                Parent = this,
                Data = pictures,
                ControlSize = new Size(devAreaObjects.Width, 35),
                Spacing = new Size(4, 4),
                StartTopLeftPosition = new Point(devAreaObjects.Left, devAreaObjects.Top),
                EndBottomRightPosition = new Point(devAreaObjects.Right, devAreaObjects.Bottom)
            };

            pagingPictures.SetPageDependentControlData += new EventHandler<SetPageDependentControlDataEventArgs<Area, string>>(pagingPictures_SetPageDependentControlData);
            pagingPictures.PageChanged += new EventHandler<PageChangedEventArgs>(paging_PageChanged);
            pagingPictures.InitializeControl += new EventHandler<ControlEventArgs<Area>>(pagingPictures_InitializeControl);
            pagingPictures.VisibleChanged += new EventHandler(pagingPictures_VisibleChanged);
            pagingPictures.InitializeControls();
        }

        void LoadActivites()
        {
            pagingActivities = new PagingIDBased<Area, Activity>()
            {
                Parent = this,
                Data = Settings.Default.Data.Activites,
                ControlSize = new Size(devAreaActivities.Width, 40),
                Spacing = new Size(4, 4),
                StartTopLeftPosition = new Point(devAreaActivities.Left, devAreaActivities.Top),
                EndBottomRightPosition = new Point(devAreaActivities.Right, devAreaActivities.Bottom)
            };

            pagingActivities.SetPageDependentControlData += new EventHandler<SetPageDependentControlDataEventArgs<Area, Activity>>(pagingActivities_SetPageDependentControlData);
            pagingActivities.InitializeControl += new EventHandler<ControlEventArgs<Area>>(pagingActivities_InitializeControl);
            pagingActivities.InitializeControls();


            pagingActivityPrograms = new PagingIDBased<Area, Activity.Program>()
            {
                Parent = this,
                ControlSize = new Size(devAreaActivityPrograms.Width, 40),
                Spacing = new Size(4, 4),
                StartTopLeftPosition = new Point(devAreaActivityPrograms.Left, devAreaActivityPrograms.Top),
                EndBottomRightPosition = new Point(devAreaActivityPrograms.Right, devAreaActivityPrograms.Bottom)
            };

            pagingActivityPrograms.SetPageDependentControlData += new EventHandler<SetPageDependentControlDataEventArgs<Area, Activity.Program>>(pagingActivityPrograms_SetPageDependentControlData);
            pagingActivityPrograms.InitializeControl += new EventHandler<ControlEventArgs<Area>>(pagingActivityPrograms_InitializeControl);
            pagingActivityPrograms.InitializeControls();
        }


        void pagingActivityPrograms_InitializeControl(object sender, ControlEventArgs<Area> e)
        {
            e.Control.RoundCorners = Corner.All;
            e.Control.RoundRadius = 40;
            e.Control.SoundEffect = SoundEffect.Beep2;
            e.Control.TextPadding = new Padding(10, 0, 10, 0);
            e.Control.Behaviour = Behaviour.Click;
            e.Control.AutoEllipsis = true;
            e.Control.Color = Colors.Blue4;
            e.Control.Font = new System.Drawing.Font("LCARSGTJ3", 25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);

            e.Control.Click += new EventHandler(ActivityProgramObject_Click);
        }

        void ActivityProgramObject_Click(object sender, EventArgs e)
        {
            Process process = new Process();
            process.StartInfo.WorkingDirectory = Path.GetDirectoryName((sender as Area).Tag.ToString());
            process.StartInfo.FileName = (sender as Area).Tag.ToString();
            process.Start();
        }

        void pagingActivityPrograms_SetPageDependentControlData(object sender, SetPageDependentControlDataEventArgs<Area, Activity.Program> e)
        {
            e.Control.Text = e.Data.Name;
            e.Control.Tag = e.Data.Path;
        }


        void pagingActivities_InitializeControl(object sender, ControlEventArgs<Area> e)
        {
            e.Control.RoundCorners = Corner.All;
            e.Control.RoundRadius = 40;
            e.Control.SoundEffect = SoundEffect.Beep2;
            e.Control.TextPadding = new Padding(10, 0, 10, 0);
            e.Control.Behaviour = Behaviour.Click;
            e.Control.AutoEllipsis = true;
            e.Control.Color = Colors.Blue3;
            e.Control.Font = new System.Drawing.Font("LCARSGTJ3", 25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);

            e.Control.Click += new EventHandler(ActivityObject_Click);
        }

        void ActivityObject_Click(object sender, EventArgs e)
        {
            Activity activity = ((sender as Control).Tag as Activity);
            if (pagingActivityPrograms.Visible && pagingActivityPrograms.Data == activity.Programs)
            {
                pagingActivityPrograms.Hide();
                return;
            }

            pagingActivityPrograms.Data = activity.Programs;
            pagingActivityPrograms.Show();
        }

        void pagingActivities_SetPageDependentControlData(object sender, SetPageDependentControlDataEventArgs<Area, Activity> e)
        {
            e.Control.Text = e.Data.Name;
            e.Control.Tag = e.Data;
        }


        #region Music

        void pagingMusic_InitializeControl(object sender, ControlEventArgs<MusicObject> e)
        {
            e.Control.Click += new EventHandler<MusicObjectEventArgs>(MusicObject_Click);
        }

        void pagingMusic_SetPageDependentControlData(object sender, SetPageDependentControlDataEventArgs<MusicObject, string> e)
        {
            e.Control.Text = Path.GetFileName(e.Data);
            e.Control.Tag = e.Data;
        }

        void pagingMusic_VisibleChanged(object sender, EventArgs e)
        {
            if (!pagingMusic.Visible)
            {
                areaMusic.SoundEffect = SoundEffect.ViewOn;
                areaTitleSecondary.Text = String.Empty;
            }
            else
            {
                areaMusic.SoundEffect = SoundEffect.ViewOff;
                areaTitleSecondary.Text = "Musik";
            }
        }

        void MusicObject_Click(object sender, MusicObjectEventArgs e)
        {
            Process process = new Process();
            process.StartInfo.FileName = Settings.Default.Data.VLCPath;

            if (e.Secondary)
                process.StartInfo.Arguments = string.Format("--started-from-file --no-qt-notification --qt-start-minimized --playlist-enqueue \"{0}\"", (sender as Control).Tag.ToString());
            else
                process.StartInfo.Arguments = string.Format("--started-from-file --no-qt-notification --qt-start-minimized \"{0}\"", (sender as Control).Tag.ToString());

            process.Start();
        }

        #endregion

        #region Documents

        void pagingDocuments_InitializeControl(object sender, ControlEventArgs<Area> e)
        {
            e.Control.RoundCorners = Corner.All;
            e.Control.RoundRadius = 35;
            e.Control.SoundEffect = SoundEffect.Beep2;
            e.Control.TextPadding = new Padding(10, 0, 10, 0);
            e.Control.Behaviour = Behaviour.Click;
            e.Control.AutoEllipsis = true;
            e.Control.Color = Colors.Orange5;
            e.Control.Font = new System.Drawing.Font("LCARSGTJ3", 25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
            e.Control.Click += new EventHandler(DocumentObject_Click);
        }

        void pagingDocuments_SetPageDependentControlData(object sender, SetPageDependentControlDataEventArgs<Area, string> e)
        {
            e.Control.Text = Path.GetFileName(e.Data);
            e.Control.Tag = e.Data;
        }

        void pagingDocuments_VisibleChanged(object sender, EventArgs e)
        {
            if (!pagingDocuments.Visible)
            {
                areaDocuments.SoundEffect = SoundEffect.ViewOn;
                areaTitleSecondary.Text = String.Empty;
            }
            else
            {
                areaDocuments.SoundEffect = SoundEffect.ViewOff;
                areaTitleSecondary.Text = "Dokumente";
            }
        }

        void DocumentObject_Click(object sender, EventArgs e)
        {
            Process process = new Process();
            process.StartInfo.UseShellExecute = true;
            process.StartInfo.FileName = (sender as Control).Tag.ToString();
            process.Start();
        }

        #endregion

        #region Pictures

        void pagingPictures_InitializeControl(object sender, ControlEventArgs<Area> e)
        {
            e.Control.RoundCorners = Corner.All;
            e.Control.RoundRadius = 35;
            e.Control.SoundEffect = SoundEffect.Beep2;
            e.Control.TextPadding = new Padding(10, 0, 10, 0);
            e.Control.Behaviour = Behaviour.Click;
            e.Control.AutoEllipsis = true;
            e.Control.Color = Colors.Orange5;
            e.Control.Font = new System.Drawing.Font("LCARSGTJ3", 25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
            e.Control.Click += new EventHandler(PictureObject_Click);
        }

        void pagingPictures_SetPageDependentControlData(object sender, SetPageDependentControlDataEventArgs<Area, string> e)
        {
            e.Control.Text = Path.GetFileName(e.Data);
            e.Control.Tag = e.Data;
        }

        void pagingPictures_VisibleChanged(object sender, EventArgs e)
        {
            if (!pagingPictures.Visible)
            {
                areaPictures.SoundEffect = SoundEffect.ViewOn;
                areaTitleSecondary.Text = String.Empty;
            }
            else
            {
                areaPictures.SoundEffect = SoundEffect.ViewOff;
                areaTitleSecondary.Text = "Bilder";
            }
        }

        void PictureObject_Click(object sender, EventArgs e)
        {
            Process process = new Process();
            process.StartInfo.UseShellExecute = true;
            process.StartInfo.FileName = (sender as Control).Tag.ToString();
            process.Start();
        }

        #endregion


        void paging_PageChanged(object sender, PageChangedEventArgs e)
        {
            if (e.PreviousPageAvailable)
                areaPreviousPage.SoundEffect = LCARSLibrary.SoundEffect.Beep2;
            else
                areaPreviousPage.SoundEffect = LCARSLibrary.SoundEffect.Error1;

            if (e.NextPageAvailable)
                areaNextPage.SoundEffect = LCARSLibrary.SoundEffect.Beep2;
            else
                areaNextPage.SoundEffect = LCARSLibrary.SoundEffect.Error1;
        }




        private void areaNextPage_Click(object sender, EventArgs e)
        {
            if (pagingMusic.Visible)
                pagingMusic.GoToPage(pagingMusic.CurrentPage + 1);
            else if (pagingDocuments.Visible)
                pagingDocuments.GoToPage(pagingDocuments.CurrentPage + 1);
            else if (pagingPictures.Visible)
                pagingPictures.GoToPage(pagingPictures.CurrentPage + 1);
        }

        private void areaPreviousPage_Click(object sender, EventArgs e)
        {
            if (pagingMusic.Visible)
                pagingMusic.GoToPage(pagingMusic.CurrentPage - 1);
            else if (pagingDocuments.Visible)
                pagingDocuments.GoToPage(pagingDocuments.CurrentPage - 1);
            else if (pagingPictures.Visible)
                pagingPictures.GoToPage(pagingPictures.CurrentPage - 1);
        }


        private void areaMusic_Click(object sender, EventArgs e)
        {
            if (pagingMusic.Visible)
            {
                pagingMusic.Hide();
                return;
            }

            pagingDocuments.Hide();
            pagingPictures.Hide();

            pagingMusic.Show();
        }

        private void areaDocuments_Click(object sender, EventArgs e)
        {
            if (pagingDocuments.Visible)
            {
                pagingDocuments.Hide();
                return;
            }

            pagingPictures.Hide();
            pagingMusic.Hide();

            pagingDocuments.Show();
        }

        private void areaPictures_Click(object sender, EventArgs e)
        {
            if (pagingPictures.Visible)
            {
                pagingPictures.Hide();
                return;
            }

            pagingDocuments.Hide();
            pagingMusic.Hide();

            pagingPictures.Show();
        }


        #region Multimedia Control

        private void areaPlay_Click(object sender, EventArgs e)
        {
            vlcInterface.Play();
        }

        private void areaPause_Click(object sender, EventArgs e)
        {
            vlcInterface.Pause();
        }

        private void areaMute_Click(object sender, EventArgs e)
        {
            vlcInterface.VolumeMute();
        }

        private void areaVolumeDown_Click(object sender, EventArgs e)
        {
            vlcInterface.VolumeDown();
        }

        private void areaVolumeUp_Click(object sender, EventArgs e)
        {
            vlcInterface.VolumeUp();
        }

        private void areaNextTrack_Click(object sender, EventArgs e)
        {
            vlcInterface.NextTrack();
        }

        private void areaPreviousTrack_Click(object sender, EventArgs e)
        {
            vlcInterface.PreviousTrack();
        }

        private void areaStop_Click(object sender, EventArgs e)
        {
            vlcInterface.Stop();
        }

        #endregion


        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_HOTKEY:
                    {
                        if (m.WParam == (IntPtr)1)
                        {
                            if (!this.Visible)
                                areaMinimize.PlaySoundEffect();

                            this.Show();
                            //this.WindowState = FormWindowState.Normal;
                            //SetWindowPos(m.HWnd, IntPtr.Zero/*HWND_TOP*/, 0, 0, 0, 0, 0x02/*SWP_NOMOVE*/ | 0x01/*SWP_NOSIZE*/);
                            SetForegroundWindow(m.HWnd);
                            this.Focus();
                        }

                        break;
                    }
            }

            base.WndProc(ref m);
        }


        private void Form3_FormClosed(object sender, FormClosedEventArgs e)
        {
            UnregisterHotKey(this.Handle, 1);
        }

        private void areaMinimize_Click(object sender, EventArgs e)
        {
            this.Hide();
        }

        private void areaClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void areaActivities_Click(object sender, EventArgs e)
        {
            if (pagingActivities.Visible)
            {
                pagingActivities.Hide();
                pagingActivityPrograms.Hide();
                return;
            }

            pagingActivities.Show();
        }


        bool b = true;

        private void area17_Click(object sender, EventArgs e)
        {
            if (b)
            {
                vlcInterface.Pause();
                LCARSBase.ExclusiveLoopPlaying = true;
                LCARSBase.FlashInterval = 150;
                LCARSBase.PlaySoundEffect(SoundEffect.RedAlert, true);
            }
            else
            {
                LCARSBase.ExclusiveLoopPlaying = false;
                LCARSBase.FlashInterval = 470;
                LCARSBase.StopPlaying();
            }


            foreach (var key in redAlertFlashingCtrls.Keys)
            {
                foreach (var item in redAlertFlashingCtrls[key])
                {
                    item.Flash(b, Colors.Red3, Color.White, key, item == area4 ? true : false);
                }
            }

            b = !b;
        }

        private void area8_Click(object sender, EventArgs e)
        {
            foreach (var item in LCARSBase.GetGroupControls(ControlGroup.Group10))
            {
                if (item.Visible)
                    item.Hide();
                else
                    item.Show();
            }
        }

        private void area33_Click(object sender, EventArgs e)
        {
            //Reset Bounds
            this.Bounds = new Rectangle(Screen.PrimaryScreen.WorkingArea.Location, new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height - 2));
        }

        private void area54_Click(object sender, EventArgs e)
        {
            verbalInterface.SimulateCommand("Computer", false);
        }

        private void area55_Click(object sender, EventArgs e)
        {
            verbalInterface.SimulateCommand("Befehl zurück", false);
        }

        private void area56_Click(object sender, EventArgs e)
        {
            verbalInterface.SimulateCommand("Aktivitäten", false);

        }

        private void area57_Click(object sender, EventArgs e)
        {
            verbalInterface.SimulateCommand("Spiele", false);

        }

        private void area58_Click(object sender, EventArgs e)
        {
            verbalInterface.SimulateCommand("Deaktivieren", false);

        }

        private void area59_Click(object sender, EventArgs e)
        {
            verbalInterface.SimulateCommand("beenden", false);

        }

        private void area60_Click(object sender, EventArgs e)
        {
            verbalInterface.SimulateCommand("Positiv", false);

        }

        private void area61_Click(object sender, EventArgs e)
        {
            verbalInterface.SimulateCommand("Negativ", false);

        }

        private void area62_Click(object sender, EventArgs e)
        {
            verbalInterface.SimulateCommand("Musik", false);

        }

        private void area63_Click(object sender, EventArgs e)
        {
            verbalInterface.SimulateCommand("", false);

        }

        private void area64_Click(object sender, EventArgs e)
        {
            verbalInterface.SimulateCommand(textBox1.Text, false);
        }

        private void area28_Click(object sender, EventArgs e)
        {
            if (!verbalInterface.Initialized)
                return;

            if (!verbalInterface.Active)
            {
                area28.SoundEffect = SoundEffect.Beep4;
                area28.Flash(false);
                verbalInterface.Activate();
            }
            else
            {
                verbalInterface.Deactivate();
            }
        }
    }
}
